package com.nervenets.web.controller.handler.admin.wealth;

import com.nervenets.utils.StringUtils;
import com.nervenets.web.controller.Global;
import com.nervenets.web.controller.handler.SessionHandler;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.enumeration.*;
import com.nervenets.web.hibernate.domain.user.WealthFlow;
import com.nervenets.web.rabbitmq.FlowMessage;
import com.nervenets.web.rabbitmq.FlowType;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class UserWithdrawCheckHandler extends SessionHandler<UserWithdrawCheckParams> {
    @Override
    public ArrayList<Role> allowRoles() {
        return Role.administrator();
    }

    @Override
    public boolean needLog() {
        return false;
    }

    @Override
    public String handle(UserWithdrawCheckParams params, HttpServletRequest request) throws Exception {
        return (String) redisSyncLocker.keyLock(String.format(Global.Constants.REDIS_USER_WEALTH_LOCK, params.getTargetUserId()), o -> {
            WealthFlow flow = userDao.findById(params.getWithdrawId(), WealthFlow.class);
            if (null == flow) return errorMessage(MessageCode.code_444, "您操作了不存在的流水记录！");
            if (flow.getFlowStatus().ordinal() > FlowStatus.verify.ordinal())
                return errorMessage(MessageCode.code_444, "该流水已处理，不要重复处理！");
            if (params.getTargetUserId() != flow.getUserId())
                return errorMessage(MessageCode.code_444, "该账务流水不是该用户的！");

            if (!params.isSuccess()) {//返账
                if (StringUtils.isEmpty(params.getReason())) return errorMessage(MessageCode.code_444, "失败必须要填原因");
                flow.setFlowStatus(FlowStatus.failed);
                flow.setDetail(String.format("提现失败，原因：%s", params.getReason()));
                userDao.saveOrUpdate(flow);

                HashMap<String, Object> objects = new HashMap<>();
                objects.put("unionId", flow.getUnionId());
                objects.put("operateType", OperateType.withdrawFee);
                final List<WealthFlow> fees = userDao.getAllObjectsByHql("from WealthFlow where unionId = :unionId and operateType = :operateType", objects, 0, 1);
                long fee = 0;
                if (!fees.isEmpty()) {
                    fee = fees.get(0).getOffset();
                }

                final FlowMessage message = new FlowMessage(flow.getUserId(), FlowType.wealthChange, getIp(request), flow.getId());
                message.addData("offset", Math.abs(flow.getOffset() + fee));
                message.addData("operateType", OperateType.restoreWithdraw.name());
                message.addData("detail", "提现失败退款");
                message.addData("payType", PayType.surplus.name());
                message.addData("unionType", UnionType.flow.name());
                message.addData("flowStatus", FlowStatus.success.name());
                messageProducer.flow(message);
            } else {
                try {
                    /*final User user = userDao.findById(flow.getUserId(), User.class);
                    final long amount = Math.abs(flow.getOffset());
                    final String description = "提现¥" + NumberUtil.fen2Yuan(Math.abs(flow.getOffset())) + "元";
                    final TransfersResult transfersResult = transferMoney(Global.OrderNumber.getTransfers(flow.getId()), user.getWechatId(), amount, description);
                    if (transfersResult.isSuccess()) {*/
                    flow.setFlowStatus(FlowStatus.success);
                    userDao.saveOrUpdate(flow);
                    //userDao.updateStatisticsOfTotal(new StatisticsOfTotal(0, 0, 0, flow.getOffset()));
                    //globalService.addNewWithdrawSuccess(Math.abs(flow.getOffset()));
                    /*} else {
                        return errorMessage(MessageCode.code_302, transfersResult.getErr_code_des());
                    }*/
                } catch (Exception e) {
                    e.printStackTrace();
                    return errorMessage(MessageCode.code_403);
                }
            }
            return successMessage();
        }, null);
    }

    @Override
    public String result() throws Exception {
        return successMessage();
    }
}
